package ru.jexp.rcp.supply.swtext;

import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.databinding.observable.value.IValueChangeListener;
import org.eclipse.core.databinding.observable.value.ValueChangeEvent;
import org.eclipse.jface.window.Window;

import ru.jexp.mvc.Event;
import ru.jexp.mvc.IListener;
import ru.jexp.utilities.StringUtil;

public class LookupField<ReturnedT, LookupT extends ILookup<ReturnedT>>
{
	public interface IView
	{
		String LOOKUP = "lookup";

		IObservableValue getText();

		IObservableValue getTextEditable();

		void addLookupHandler(IListener listener);

	}

	private LookupT lookup;
	private IView view;
	private Object filter;
	private Class<ReturnedT> _class;
	private JExpConverter converter = JExpConverter.STANDART_CONVERTER;

	public LookupField(LookupField.IView view, LookupT lookup, Class<ReturnedT> _class)
	{
		this.view = view;
		this.lookup = lookup;
		this._class = _class;

		addHandlers();
	}

	public void setValue(ReturnedT value)
	{
		view.getText().setValue(getText(value));
		lookup.setChooseElement(value);
	}

	public ReturnedT getValue()
	{
		return lookup.getChooseElement();
	}

	public void setLookupInput(Object filter)
	{
		this.filter = filter;
	}

	public LookupT getLookup()
	{
		return lookup;
	}

	public ILookupFieldObservableValue observe()
	{
		return new LookupFieldValueProperty<ReturnedT, LookupT>(_class).observe(this);
	}

	protected String getText(ReturnedT value)
	{
		return converter.convert(value);
	}

	private void addHandlers()
	{
		view.addLookupHandler(new IListener()
		{
			@Override
			public void handle(Event e)
			{
				onLookup();
			}
		});

		view.getText().addValueChangeListener(new IValueChangeListener()
		{
			@Override
			public void handleValueChange(ValueChangeEvent event)
			{
				onClear();
			}
		});
	}

	protected void onClear()
	{
		String value = (String) view.getText().getValue();
		if (StringUtil.isEmptyWithoutSpace(value))
		{
			setValue(null);
		}
	}

	protected void onLookup()
	{
		if (Window.OK == lookup.open(filter))
		{
			setValue(lookup.getChooseElement());
		}
	}

	public LookupField.IView getView()
	{
		return view;
	}

	public void setConverter(JExpConverter converter)
	{
		this.converter = converter;
	}
}
